package com.newtouch.xcd.admin.mft.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.dubbo.config.annotation.Reference;
import com.newtouch.xcd.admin.config.JwtConfig;
import com.newtouch.xcd.cms.entity.*;
import com.newtouch.xcd.cms.service.*;
import com.newtouch.xcd.cms.to.crm.*;
import com.newtouch.xcd.common.constants.BaseDict;
import com.newtouch.xcd.common.constants.CrmDict;
import com.newtouch.xcd.common.constants.ResponseCode;
import com.newtouch.xcd.common.to.CommonResult;
import com.newtouch.xcd.common.utils.DateUtils;
import com.newtouch.xcd.common.utils.EnumTools;
import com.newtouch.xcd.common.utils.NumberUtils;
import com.newtouch.xcd.common.utils.StrUtils;
import com.newtouch.xcd.mft.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@CrossOrigin
@RestController
@Api(tags = "MftController", description = "2.2 我的家族信托模块mft(myFamilyTrust)")
@RequestMapping("/mft")
public class MftController {

    @Autowired
    private JwtConfig jwtConfig;

    @Reference
    private TrustService trustService;

    @Reference
    private ContractService contractService;

    @Reference
    private CustomerService customerService;

    @Reference
    private UserService userService;

    @Reference
    private RoleService roleService;

    @Reference
    private CrmService crmService;

    @Reference
    private PositionService positionService;

    @Reference
    private TrusteeService trusteeService;

    @Reference
    private MonitorService monitorService;

    @Reference
    private DistributionService distributionService;

    @Reference
    private ProductService productService;

    @ApiOperation(value = "2.2.01 查询我的家族信托")
    @PostMapping(value = "/getMyFamilyTrustList")
    public CommonResult<MftGetMyFamilyTrustListRsp> mftGetMyFamilyTrustList(HttpServletRequest request) {
        String customId = (String) request.getAttribute("identityId");

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        List<Trust> trustList = this.trustService.queryByCustomId(customId);

        if (CollUtil.isEmpty(trustList)) {
            return CommonResult.error(ResponseCode.R402.getCode(), ResponseCode.R402.getMessage());
        }

        String managerRoleId = Convert.toStr(customer.getOwnerRoleId());

        //客户经理
        User manager = this.userService.queryByRoleId(managerRoleId);
        String managerName = null;

        if (manager != null) {
            managerName = manager.getFullName();
        }

        MftGetMyFamilyTrustListRsp rsp = new MftGetMyFamilyTrustListRsp();
        if (CollUtil.isEmpty(trustList)) {
            rsp.setRecord("0");
            return CommonResult.success(rsp);
        }

        String record = Convert.toStr(trustList.size());
        List<MyFamilyItem> myFamilyTrustList = new ArrayList<>();
        for (Trust trust : trustList) {
            MyFamilyItem myFamilyItem = new MyFamilyItem();
            myFamilyItem.setXtNumber(trust.getXtNumber());
            myFamilyItem.setManagerName(managerName);

            //合同
            String trustId = Convert.toStr(trust.getTrustId());
            Contract contract = this.contractService.queryByTrustId(trustId);
            if (contract != null) {
                myFamilyItem.setXtName(contract.getContractName());
                myFamilyItem.setXtDueDate(DateUtils.formatUnixTime(Convert.toStr(contract.getDueTime() * 1000L), "yyyy/MM/dd"));
            }

            myFamilyTrustList.add(myFamilyItem);
        }
        rsp.setMyFamilyTrustList(myFamilyTrustList);
        rsp.setRecord(record);
        return CommonResult.success(rsp);
    }

    @ApiOperation(value = "2.2.02查找客户经理详细")
    @PostMapping(value = "/getManagerDetail")
    public CommonResult<MftGetManagerDetailRsp> mftGetManagerDetail(HttpServletRequest request) {
        String customId = (String) request.getAttribute("identityId");

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        String managerRoleId = Convert.toStr(customer.getOwnerRoleId());
        ManagerDetailItem managerDetailItem = new ManagerDetailItem();
        managerDetailItem.setManageRoleId(managerRoleId);

        //客户经理
        User manager = this.userService.queryByRoleId(managerRoleId);
        if (manager == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户经理不存在");
        }

        managerDetailItem.setUserCode(manager.getNumber());
        managerDetailItem.setName(manager.getFullName());
        managerDetailItem.setPhone(manager.getTelephone());

        try {
            Role role = this.roleService.getById(managerRoleId);
            Position position = this.positionService.getById(role.getPositionId());
            String positionName = position.getName();
            managerDetailItem.setJob(positionName);
        } catch (Exception e) {
            managerDetailItem.setJob(null);
        }

        MftGetManagerDetailRsp rsp = new MftGetManagerDetailRsp(managerDetailItem);

        return CommonResult.success(rsp);
    }


    /**
     * 2.2.03信托概况-主页面
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.03信托概况-主页面")
    @PostMapping(value = "/getTrustOverviewMainPage")
    public CommonResult<MftGetTrustOverviewMainPageRsp> mftGetTrustOverviewMainPage(@Valid @RequestBody MftGetTrustOverviewMainPageReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        String trustId = Convert.toStr(trust.getTrustId());
        //获得合同
        Contract contract = this.contractService.queryByTrustId(trustId);
        if (contract == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "合同不存在");
        }

        //获得交易记录缓存
        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);

        TrustOverviewItem trustOverviewItem = new TrustOverviewItem();
        trustOverviewItem.setTotalTrustAssets(NumberUtils.formatMoney(this.trustService.calTotalValueOfTrustProperty(xtNumber, crmData)));
        trustOverviewItem.setXtNumber(xtNumber);
        trustOverviewItem.setXtName(contract.getContractName());
        trustOverviewItem.setXtDueDate(DateUtils.formatUnixTime(Convert.toStr(contract.getDueTime() * 1000L), "yyyy/MM/dd"));
        trustOverviewItem.setClient(trust.getClient());

        //信托受托人
        String trusteeId = Convert.toStr(trust.getShoutuoren());

        Trustee trustee = this.trusteeService.getById(trusteeId);


        trustOverviewItem.setTrustee(trustee.getName());
        trustOverviewItem.setClient(customer.getName());
        trustOverviewItem.setProtector("新财道");

        String kaihuhang = contract.getKaihuhang();
        trustOverviewItem.setKeeper(StrUtils.queryBankName(kaihuhang));

        //检查人
        List<MonitorItem> monitorItemList = new ArrayList<>();
        String contractId = Convert.toStr(contract.getContractId());
        List<Monitor> monitors = this.monitorService.queryByContractId(contractId);
        if (CollUtil.isNotEmpty(monitors)) {
            for (Monitor monitor : monitors) {
                MonitorItem monitorItem = new MonitorItem(monitor.getName(), monitor.getTelephone());
                monitorItemList.add(monitorItem);
            }
        }

        trustOverviewItem.setMonitorItemList(monitorItemList);
        trustOverviewItem.setMonitorNum(Convert.toStr(monitorItemList.size()));

        //受益人
        List<BeneficiaryItem> beneficiaryList = this.distributionService.queryBeneficiaryItemByContractId(contractId);
        trustOverviewItem.setBeneficiaryList(beneficiaryList);

        MftGetTrustOverviewMainPageRsp rsp = new MftGetTrustOverviewMainPageRsp();
        rsp.setTrustOverview(trustOverviewItem);

        return CommonResult.success(rsp);
    }

    /**
     * 2.2.04查询信托财产状况
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.04查询信托财产状况")
    @PostMapping(value = "/getTrustPropertyStatus")
    public CommonResult<MftGetTrustPropertyStatusRsp> mftGetTrustPropertyStatus(@Valid @RequestBody MftGetTrustPropertyStatusReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        //获得交易记录缓存
        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);

        MftGetTrustPropertyStatusRsp rsp = new MftGetTrustPropertyStatusRsp();
        rsp.setInitialAdditionalTrustProperty(NumberUtils.formatMoney(this.trustService.calInitialAdditionalTrustProperty(xtNumber, crmData)));

        //C1-2020-6-24-张老师要求改的，见客户系统展示要素-我的家族信托-2020.6.24.xlsx
        rsp.setAssetAllocation(NumberUtils.formatMoney(this.trustService.calC1(xtNumber, crmData)));
        rsp.setCumulativeIncome(NumberUtils.formatMoney(this.trustService.calC2(xtNumber, crmData)));
        rsp.setDistributionOfTrustBenefits(NumberUtils.formatMoney(this.trustService.calDistributionOfTrustBenefits(xtNumber, crmData)));
        rsp.setTotalFees(NumberUtils.formatMoney(this.trustService.calTotalFees(xtNumber, crmData)));
        rsp.setCreditInsuranceFundOccupation(NumberUtils.formatMoney(this.trustService.calCreditInsuranceFundOccupation(xtNumber, crmData)));
        rsp.setTrustAccountBalance(NumberUtils.money(crmData.getTrustAccountBalance()));

        return CommonResult.success(rsp);
    }

    /**
     * 2.2.05查询初始追加信托财产
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.05查询初始追加信托财产")
    @PostMapping(value = "/getInitialAdditionalTrustProperty")
    public CommonResult<MftGetInitialAdditionalTrustPropertyRsp> mftGetInitialAdditionalTrustProperty(@Valid @RequestBody MftGetInitialAdditionalTrustPropertyReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        //获得交易记录缓存
        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);

        CrmInitialAdditionalTrustPropertyItem crmInitialAdditionalTrustPropertyItem = crmData.getInitialAdditionalTrustProperty();
        String total = crmInitialAdditionalTrustPropertyItem.getTotal();
        List<CrmInitialAdditionalTrustPropertyDetailItem> crmInitialAdditionalTrustPropertyDetailItems = crmInitialAdditionalTrustPropertyItem.getInitialAdditionalTrustPropertyList();

        //按年份分组
        Map<String, List<CrmInitialAdditionalTrustPropertyDetailItem>> yearMap = crmInitialAdditionalTrustPropertyDetailItems.stream().collect(Collectors.groupingBy(o -> DateUtils.format(o.getPaymentDate(), "yyyy-MM-dd", "yyyy")));

        List<TrustPropertyYearStatisticItem> yearRspItems = new ArrayList<>();

        for (String year : yearMap.keySet()) {

            List<CrmInitialAdditionalTrustPropertyDetailItem> yearItems = yearMap.get(year);

            TrustPropertyYearStatisticItem yearRspItem = new TrustPropertyYearStatisticItem();
            yearRspItem.setYear(year);
            yearRspItem.setInTotal(NumberUtils.formatMoney(yearItems.stream().filter(o -> "初始信托财产".equals(o.getProject())).mapToDouble(o -> Convert.toDouble(NumberUtils.formatNumber(o.getAmount()))).sum()));
            yearRspItem.setAddTotal(NumberUtils.formatMoney(yearItems.stream().filter(o -> "追加信托财产".equals(o.getProject())).mapToDouble(o -> Convert.toDouble(NumberUtils.formatNumber(o.getAmount()))).sum()));

            List<TrustPropertyPaymentItem> trustPropertyPaymentList = new ArrayList<>();

            for (CrmInitialAdditionalTrustPropertyDetailItem yearItem : yearItems) {

                TrustPropertyPaymentItem item = new TrustPropertyPaymentItem();
                item.setPropertyType(yearItem.getProject());
                item.setPaymentDate(DateUtils.format(yearItem.getPaymentDate(), "yyyy-MM-dd", "MM/dd"));
                item.setPaymentAmount(NumberUtils.formatMoney(NumberUtils.formatNumber(yearItem.getAmount())));
                trustPropertyPaymentList.add(item);
            }

            //trustPropertyPaymentList需要根据日期排序
            trustPropertyPaymentList.sort(Comparator.comparing(TrustPropertyPaymentItem::getPaymentDate).reversed());

            yearRspItem.setTrustPropertyPaymentList(trustPropertyPaymentList);

            yearRspItems.add(yearRspItem);
        }

        //根据年份排序
        yearRspItems.sort(Comparator.comparing(TrustPropertyYearStatisticItem::getYear).reversed());

        //第一个展开
        if (CollUtil.isNotEmpty(yearRspItems)) {
            yearRspItems.get(0).setOpenFlag(BaseDict.OpenFlag.OPEN.getCode());
        }

        MftGetInitialAdditionalTrustPropertyRsp rsp = new MftGetInitialAdditionalTrustPropertyRsp();
        rsp.setInTotal(NumberUtils.formatMoney(NumberUtils.formatNumber(total)));
        rsp.setYearStatisticList(yearRspItems);

        return CommonResult.success(rsp);
    }

    /**
     * 2.2.06我的信托-查询资产配置
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.06我的信托-查询资产配置")
    @PostMapping(value = "/queryAssetAllocation")
    public CommonResult<MftQueryAssetAllocationRsp> mftQueryAssetAllocation(@Valid @RequestBody MftQueryAssetAllocationReq req, BindingResult result, HttpServletRequest request) {

        String pastYear = req.getPastYear();

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);

        //资产配置（对象）
        CrmAssetAllocationItem crmAssetAllocationItem = crmData.getAssetAllocation();

        //资产配置（存期）对象
        CrmAssetAllocationDetailItem assetAllocationStoragePeriod = crmAssetAllocationItem.getAssetAllocationStoragePeriod();

        //获得存期的产品列表
        List<CrmAssetAllocationProductItem> cxCrmAssetAllocationProductItems = assetAllocationStoragePeriod.getAssetAllocationProductList();

        //存期的产品列表对产品的客户类别进行分组
        List<AssetAllocationRateItem> cxAssetAllocationRateList = prepareAssetAllocationRateItems(cxCrmAssetAllocationProductItems);

        List<AssetAllocationProductItem> cxAssetAllocationProductList = new ArrayList<>();
        cxCrmAssetAllocationProductItems.forEach(o -> {

            String productName = o.getProject();
            //表里面取出产品数据
            Product product = this.productService.queryByName(productName);


            AssetAllocationProductItem assetAllocationProductItem = new AssetAllocationProductItem();
            if (product != null) {
                assetAllocationProductItem.setProductId(Convert.toStr(product.getProductId()));
                //预期收益率
                Float expectedProfits = product.getYqsyl();
                if (expectedProfits != null && expectedProfits > 0) {
                    assetAllocationProductItem.setExpectedProfits(NumberUtils.money(expectedProfits, "#.#"));
                }

            }
            assetAllocationProductItem.setProductName(StrUtils.calFinProductName(productName));

            String startDate = o.getShareConfirmationDate();
            if ("0000-00-00".equals(startDate)) {
                startDate = "";
            } else if (StrUtils.isNotBlank(startDate)) {
                startDate = DateUtils.format(startDate, "yyyy-MM-dd", "yyyy/MM/dd");
            } else {
                startDate = "";
            }

            String productRange = "";

            String endDate = o.getDeadDate();
            if ("0000-00-00".equals(endDate)) {
                productRange = startDate;
            } else if (StrUtils.isNotBlank(endDate)) {
                endDate = DateUtils.format(endDate, "yyyy-MM-dd", "yyyy/MM/dd");
                productRange = startDate + "-" + endDate;
            } else {
                productRange = startDate;
            }

            assetAllocationProductItem.setProductRange(productRange);
            assetAllocationProductItem.setConfigAmount(NumberUtils.money(o.getAmount()));

            assetAllocationProductItem.setEarnedIncome(NumberUtils.money(o.getEarnedIncome()));
            assetAllocationProductItem.setAssetAllocationType(o.getCustomerProductCategory());
            cxAssetAllocationProductList.add(assetAllocationProductItem);
        });

        //按产品区间范围倒序排序
        cxAssetAllocationProductList.sort(Comparator.comparing(AssetAllocationProductItem::getProductRange).reversed());

        //资产配置（到期）对象
        CrmAssetAllocationDetailItem assetAllocationMaturity = crmAssetAllocationItem.getAssetAllocationMaturity();

        //获得到期的产品列表
        List<CrmAssetAllocationProductItem> dxCrmAssetAllocationProductItems = assetAllocationMaturity.getAssetAllocationProductList();

        List<String> pastYearList = new ArrayList<>();

        Map<String, List<AssetAllocationRateItem>> dxYearRateMap = new HashMap<>();
        Map<String, List<AssetAllocationProductItem>> dxYearProductMap = new HashMap<>();

        if (CollUtil.isNotEmpty(dxCrmAssetAllocationProductItems)) {
            //到期产品的最小的日期
            Integer minDateInt = dxCrmAssetAllocationProductItems.stream().mapToInt(o -> Convert.toInt(DateUtils.format(o.getShareConfirmationDate(), "yyyy-MM-dd", "yyyyMMdd"))).min().getAsInt();
            //到期产品的最大的日期
            Integer maxDateInt = dxCrmAssetAllocationProductItems.stream().mapToInt(o -> Convert.toInt(DateUtils.format(o.getDeadDate(), "yyyy-MM-dd", "yyyyMMdd"))).max().getAsInt();

            String minDate = Convert.toStr(minDateInt);
            String maxDate = Convert.toStr(maxDateInt);

            pastYearList = DateUtils.years(minDate, maxDate, "yyyyMMdd");

            //按年来循环
            pastYearList.forEach(year -> {

                List<CrmAssetAllocationProductItem> dxYearProductList = dxCrmAssetAllocationProductItems.stream().filter(o ->
                        DateUtils.checkTimesHasOverlap(DateUtils.parse(o.getShareConfirmationDate()), DateUtils.parse(o.getDeadDate()), DateUtils.parse(year + "-01-01"), DateUtils.parse(year + "-12-31"))
                ).collect(Collectors.toList());

                //存期的产品列表对产品的客户类别进行分组
                List<AssetAllocationRateItem> dxAssetAllocationRateList = prepareAssetAllocationRateItems(dxYearProductList);
                dxYearRateMap.put(year, dxAssetAllocationRateList);

                List<AssetAllocationProductItem> dxAssetAllocationProductList = new ArrayList<>();
                dxYearProductList.forEach(p -> {
                    String productName = p.getProject();
                    //表里面取出产品数据
                    Product product = this.productService.queryByName(productName);

                    AssetAllocationProductItem assetAllocationProductItem = new AssetAllocationProductItem();
                    if (product != null) {
                        assetAllocationProductItem.setProductId(Convert.toStr(product.getProductId()));

                        //预期收益率
                        Float expectedProfits = product.getYqsyl();
                        if (expectedProfits != null && expectedProfits > 0) {
                            assetAllocationProductItem.setExpectedProfits(NumberUtils.money(expectedProfits, "#.#"));
                        }

                    }
                    assetAllocationProductItem.setProductName(StrUtils.calFinProductName(productName));

                    String startDate = p.getShareConfirmationDate();
                    if (StrUtils.isNotBlank(startDate)) {
                        startDate = DateUtils.format(startDate, "yyyy-MM-dd", "yyyy/MM/dd");
                    }


                    String productRange = "";

                    String endDate = p.getDeadDate();
                    if (StrUtils.isNotBlank(endDate)) {
                        endDate = DateUtils.format(endDate, "yyyy-MM-dd", "yyyy/MM/dd");
                        productRange = startDate + "-" + endDate;
                    } else {
                        productRange = startDate;
                    }

                    assetAllocationProductItem.setProductRange(productRange);
                    assetAllocationProductItem.setConfigAmount(NumberUtils.money(p.getAmount()));

                    List<CrmAssetAllocationProductIncomeItem> incomeItems = p.getIncomeList();
                    incomeItems = incomeItems.stream().filter(i -> year.equals(DateUtils.format(i.getBenefitDate(), "yyyy-MM-dd", "yyyy"))).collect(Collectors.toList());
                    assetAllocationProductItem.setEarnedIncome(NumberUtils.money(incomeItems.stream().mapToDouble(i -> Convert.toDouble(NumberUtils.formatNumber(i.getBenefitAmount()))).sum()));
                    assetAllocationProductItem.setAssetAllocationType(p.getCustomerProductCategory());
                    dxAssetAllocationProductList.add(assetAllocationProductItem);
                });

                //按产品区间范围倒序排序
                dxAssetAllocationProductList.sort(Comparator.comparing(AssetAllocationProductItem::getProductRange).reversed());

                dxYearProductMap.put(year, dxAssetAllocationProductList);
            });
        }

        MftQueryAssetAllocationRsp rsp = new MftQueryAssetAllocationRsp();

        if (StrUtils.isBlank(pastYear)) {

            AssetAllocationItem assetAllocationItem = new AssetAllocationItem();
            assetAllocationItem.setCurrentProperty("当期");
            assetAllocationItem.setAssetAllocationRateList(cxAssetAllocationRateList);
            assetAllocationItem.setAssetAllocationProductList(cxAssetAllocationProductList);
            rsp.setAssetAllocation(assetAllocationItem);
        } else if (pastYearList.contains(pastYear)) {
            AssetAllocationItem assetAllocationItem = new AssetAllocationItem();
            assetAllocationItem.setCurrentProperty(pastYear);
            assetAllocationItem.setAssetAllocationRateList(dxYearRateMap.get(pastYear));
            assetAllocationItem.setAssetAllocationProductList(dxYearProductMap.get(pastYear));
            rsp.setAssetAllocation(assetAllocationItem);
        } else {
            return CommonResult.error(ResponseCode.R407.getCode(), "往期这一年没有资产配置");
        }

        pastYearList.sort(Comparator.comparing(String::toString).reversed());

        rsp.setPastYearList(pastYearList);

        return CommonResult.success(rsp);
    }

    /**
     * 对产品的客户类别进行分组
     * 返回的集合按顺序排
     *
     * @param cxCrmAssetAllocationProductItems
     * @return
     */
    private List<AssetAllocationRateItem> prepareAssetAllocationRateItems(List<CrmAssetAllocationProductItem> cxCrmAssetAllocationProductItems) {

        //对产品的客户类别进行分组
        Map<String, List<CrmAssetAllocationProductItem>> cxProductTypeMap = cxCrmAssetAllocationProductItems.stream().collect(Collectors.groupingBy(o -> o.getCustomerProductCategory()));

        List<AssetAllocationRateItem> cxAssetAllocationRateList = new ArrayList<>();

        EnumSet<CrmDict.FundProductType> fundProductTypes = EnumSet.allOf(CrmDict.FundProductType.class);
        for (CrmDict.FundProductType fundProductTypeItem : fundProductTypes) {
            String productType = fundProductTypeItem.getMessage();
            if (cxProductTypeMap.containsKey(productType)) {
                List<CrmAssetAllocationProductItem> crmAssetAllocationProductList = cxProductTypeMap.get(productType);
                AssetAllocationRateItem assetAllocationRateItem = new AssetAllocationRateItem();
                assetAllocationRateItem.setName(productType);
                assetAllocationRateItem.setValue(NumberUtils.money(crmAssetAllocationProductList.stream().mapToDouble(o -> Convert.toDouble(NumberUtils.formatNumber(o.getAmount()))).sum(), "#"));
                cxAssetAllocationRateList.add(assetAllocationRateItem);
            } else {
                cxAssetAllocationRateList.add(new AssetAllocationRateItem());
            }
        }

        return cxAssetAllocationRateList;
    }

    /**
     * 2.2.07我的信托-查询累计收益
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.07我的信托-查询累计收益")
    @PostMapping(value = "/queryCumulativeIncome")
    public CommonResult<MftQueryCumulativeIncomeRsp> mftQueryCumulativeIncome(@Valid @RequestBody MftQueryCumulativeIncomeReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        //先取交易记录的缓存
        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);


        //累计收益总计
        BigDecimal cumulativeIncomeTotal = this.trustService.calC2(xtNumber, crmData);

        //所有的收益明细
        List<TrustCumulativeIncomeItem> allTrustCumulativeIncomeList = new ArrayList<>();


        //region获得所有的收益明细-start

        CrmAssetAllocationItem crmAssetAllocationItem = crmData.getAssetAllocation();

        //存期-资产配置明细对象
        CrmAssetAllocationDetailItem storagePeriodCrmAssetAllocationDetailItem = crmAssetAllocationItem.getAssetAllocationStoragePeriod();

        //存期的产品集合
        List<CrmAssetAllocationProductItem> storagePeriodCrmAssetAllocationProductItems = storagePeriodCrmAssetAllocationDetailItem.getAssetAllocationProductList();

        for (CrmAssetAllocationProductItem crmAssetAllocationProductItem : storagePeriodCrmAssetAllocationProductItems) {

            List<CrmAssetAllocationProductIncomeItem> incomeItems = crmAssetAllocationProductItem.getIncomeList();
            for (CrmAssetAllocationProductIncomeItem incomeItem : incomeItems) {
                TrustCumulativeIncomeItem incomeRspItem = new TrustCumulativeIncomeItem();
                incomeRspItem.setProductName(StrUtils.calFinProductName(crmAssetAllocationProductItem.getProject()));
                incomeRspItem.setIncomeDate(DateUtils.format(incomeItem.getBenefitDate(), "yyyy-MM-dd", "yyyy/MM/dd"));
                incomeRspItem.setIncomeAmount(Convert.toStr(NumberUtils.formatNumber(incomeItem.getBenefitAmount())));
                if ("1".equals(incomeItem.getArriveFlag())) {
                    allTrustCumulativeIncomeList.add(incomeRspItem);
                }
            }
        }

        //到期-资产配置明细对象
        CrmAssetAllocationDetailItem maturityCrmAssetAllocationDetailItem = crmAssetAllocationItem.getAssetAllocationMaturity();

        //到期的产品集合
        List<CrmAssetAllocationProductItem> maturityCrmAssetAllocationProductItems = maturityCrmAssetAllocationDetailItem.getAssetAllocationProductList();

        for (CrmAssetAllocationProductItem crmAssetAllocationProductItem : maturityCrmAssetAllocationProductItems) {

            List<CrmAssetAllocationProductIncomeItem> incomeItems = crmAssetAllocationProductItem.getIncomeList();
            for (CrmAssetAllocationProductIncomeItem incomeItem : incomeItems) {
                TrustCumulativeIncomeItem incomeRspItem = new TrustCumulativeIncomeItem();
                incomeRspItem.setProductName(StrUtils.calFinProductName(crmAssetAllocationProductItem.getProject()));
                incomeRspItem.setIncomeDate(DateUtils.format(incomeItem.getBenefitDate(), "yyyy-MM-dd", "yyyy/MM/dd"));
                incomeRspItem.setIncomeAmount(Convert.toStr(NumberUtils.formatNumber(incomeItem.getBenefitAmount())));
                if ("1".equals(incomeItem.getArriveFlag())) {
                    allTrustCumulativeIncomeList.add(incomeRspItem);
                }
            }
        }

        //获得所有的收益明细-end

        //按年份
        //按年份分组
        Map<String, List<TrustCumulativeIncomeItem>> yearMap = allTrustCumulativeIncomeList.stream().collect(Collectors.groupingBy(o -> DateUtils.format(o.getIncomeDate(), "yyyy/MM/dd", "yyyy")));

        //获得年收益集合
        List<TrustCumulativeIncomeYearItem> cumulativeIncomeYearList = new ArrayList<>();
        for (String year : yearMap.keySet()) {

            TrustCumulativeIncomeYearItem trustCumulativeIncomeYearItem = new TrustCumulativeIncomeYearItem();
            trustCumulativeIncomeYearItem.setYear(year);

            List<TrustCumulativeIncomeItem> trustCumulativeIncomeItems = yearMap.get(year);
            trustCumulativeIncomeItems.sort(Comparator.comparing(TrustCumulativeIncomeItem::getIncomeDate).reversed());
            trustCumulativeIncomeYearItem.setYearTotal(NumberUtils.formatMoney(trustCumulativeIncomeItems.stream().mapToDouble(o -> Convert.toDouble(o.getIncomeAmount())).sum()));
            trustCumulativeIncomeYearItem.setTrustCumulativeIncomeList(trustCumulativeIncomeItems);

            //金额格式化
            for (TrustCumulativeIncomeItem trustCumulativeIncomeItem : trustCumulativeIncomeItems) {
                trustCumulativeIncomeItem.setIncomeAmount(NumberUtils.formatMoney(trustCumulativeIncomeItem.getIncomeAmount()));
            }
            cumulativeIncomeYearList.add(trustCumulativeIncomeYearItem);
        }

        cumulativeIncomeYearList.sort(Comparator.comparing(TrustCumulativeIncomeYearItem::getYear).reversed());

        //第一个展开
        if (CollUtil.isNotEmpty(cumulativeIncomeYearList)) {
            cumulativeIncomeYearList.get(0).setOpenFlag(BaseDict.OpenFlag.OPEN.getCode());
        }

        MftQueryCumulativeIncomeRsp rsp = new MftQueryCumulativeIncomeRsp();
        rsp.setCumulativeIncomeTotal(NumberUtils.formatMoney(cumulativeIncomeTotal));
        rsp.setCumulativeIncomeYearList(cumulativeIncomeYearList);

        return CommonResult.success(rsp);
    }

    /**
     * 2.2.08我的信托-查询费用合计
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.08我的信托-查询费用合计")
    @PostMapping(value = "/queryTotalFees")
    public CommonResult<MftQueryTotalFeesRsp> mftQueryTotalFees(@Valid @RequestBody MftQueryTotalFeesReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        //先取交易记录的缓存
        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);

        //费用合计
        String costTotal = Convert.toStr(NumberUtils.formatNumber(crmData.getCost().getTotal()));

        //获取费用明细（列表）
        List<CrmCostDetailItem> crmCostDetailList = crmData.getCost().getCostList();

        //费用合计明细集合
        List<TrustTotalFeesDetailItem> trustTotalFeesDetailList = new ArrayList<>();

        //把费用0的过滤掉
        crmCostDetailList = crmCostDetailList.stream().filter(o -> BigDecimal.ZERO.compareTo(NumberUtils.formatNumber(o.getAmount())) != 0).collect(Collectors.toList());

        //region获得费用合计明细-start
        for (CrmCostDetailItem crmCostDetailItem : crmCostDetailList) {
            TrustTotalFeesDetailItem trustTotalFeesDetailItem = new TrustTotalFeesDetailItem();
            trustTotalFeesDetailItem.setCostAmount(Convert.toStr(NumberUtils.formatNumber(crmCostDetailItem.getAmount())));
            trustTotalFeesDetailItem.setCostProjectName(crmCostDetailItem.getSummary());
            trustTotalFeesDetailItem.setCostDate(DateUtils.format(crmCostDetailItem.getDeadDate(), "yyyy-MM-dd", "yyyy/MM/dd"));
            trustTotalFeesDetailList.add(trustTotalFeesDetailItem);
        }
        //获得费用合计明细-end

        //按年份分组
        Map<String, List<TrustTotalFeesDetailItem>> yearMap = trustTotalFeesDetailList.stream().collect(Collectors.groupingBy(o -> DateUtils.format(o.getCostDate(), "yyyy/MM/dd", "yyyy")));

        //获得年收益集合
        List<TrustTotalFeesYearItem> trustTotalFeesYearItems = new ArrayList<>();
        for (String year : yearMap.keySet()) {
            TrustTotalFeesYearItem trustTotalFeesYearItem = new TrustTotalFeesYearItem();
            trustTotalFeesYearItem.setYear(year);
            List<TrustTotalFeesDetailItem> trustTotalFeesDetailItems = yearMap.get(year);
            trustTotalFeesDetailItems.sort(Comparator.comparing(TrustTotalFeesDetailItem::getCostDate).reversed());
            trustTotalFeesYearItem.setYearTotal(NumberUtils.formatMoney(trustTotalFeesDetailItems.stream().mapToDouble(o -> Convert.toDouble(o.getCostAmount())).sum()));

            //金额格式化
            for (TrustTotalFeesDetailItem trustTotalFeesDetailItem : trustTotalFeesDetailItems) {
                trustTotalFeesDetailItem.setCostAmount(NumberUtils.formatMoney(trustTotalFeesDetailItem.getCostAmount()));
            }

            trustTotalFeesYearItem.setTotalFeesList(trustTotalFeesDetailItems);
            trustTotalFeesYearItems.add(trustTotalFeesYearItem);
        }

        trustTotalFeesYearItems.sort(Comparator.comparing(TrustTotalFeesYearItem::getYear).reversed());

        //第一个展开
        if (CollUtil.isNotEmpty(trustTotalFeesYearItems)) {
            trustTotalFeesYearItems.get(0).setOpenFlag(BaseDict.OpenFlag.OPEN.getCode());
        }

        MftQueryTotalFeesRsp rsp = new MftQueryTotalFeesRsp();
        rsp.setTotalFees(NumberUtils.formatMoney(costTotal));
        rsp.setTotalFeesYearList(trustTotalFeesYearItems);

        return CommonResult.success(rsp);
    }

    /**
     * 2.2.09我的信托-信保基金占用
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.09我的信托-信保基金占用")
    @PostMapping(value = "/queryCreditInsuranceFundOccupation")
    public CommonResult<MftQueryCreditInsuranceFundOccupationRsp> mftQueryCreditInsuranceFundOccupation(@Valid @RequestBody MftQueryCreditInsuranceFundOccupationReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        //先取交易记录的缓存
        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);

        //费用合计
        String creditInsuranceFundOccupiedFundTotal = Convert.toStr(NumberUtils.formatNumber(crmData.getCreditInsuranceFundOccupiedFund().getTotal()));

        //获取信保基金占用资金明细（列表）
        List<CrmCreditInsuranceFundOccupiedFundDetailItem> crmCreditInsuranceFundOccupiedFundDetailItems = crmData.getCreditInsuranceFundOccupiedFund().getCostList();

        //信保基金占用明细集合
        List<TrustCreditInsuranceFundOccupationDetailItem> trustCreditInsuranceFundOccupationDetailList = new ArrayList<>();

        //region获得信保基金占用明细集合-start
        for (CrmCreditInsuranceFundOccupiedFundDetailItem crmCreditInsuranceFundOccupiedFundDetailItem : crmCreditInsuranceFundOccupiedFundDetailItems) {
            TrustCreditInsuranceFundOccupationDetailItem trustCreditInsuranceFundOccupationDetailItem = new TrustCreditInsuranceFundOccupationDetailItem();
            trustCreditInsuranceFundOccupationDetailItem.setOccupySummary(crmCreditInsuranceFundOccupiedFundDetailItem.getSummary());
            trustCreditInsuranceFundOccupationDetailItem.setOccupyDate(DateUtils.format(crmCreditInsuranceFundOccupiedFundDetailItem.getOccupancyDate(), "yyyy-MM-dd", "yyyy/MM/dd"));
            trustCreditInsuranceFundOccupationDetailItem.setOccupyAmount(Convert.toStr(NumberUtils.formatNumber(crmCreditInsuranceFundOccupiedFundDetailItem.getAmount())));
            trustCreditInsuranceFundOccupationDetailList.add(trustCreditInsuranceFundOccupationDetailItem);
        }
        //获得信保基金占用明细集合-end

        //按年份分组
        Map<String, List<TrustCreditInsuranceFundOccupationDetailItem>> yearMap = trustCreditInsuranceFundOccupationDetailList.stream().collect(Collectors.groupingBy(o -> DateUtils.format(o.getOccupyDate(), "yyyy/MM/dd", "yyyy")));

        //获得年收益集合
        List<CreditInsuranceFundOccupationYearItem> creditInsuranceFundOccupationYearItems = new ArrayList<>();
        for (String year : yearMap.keySet()) {
            CreditInsuranceFundOccupationYearItem creditInsuranceFundOccupationYearItem = new CreditInsuranceFundOccupationYearItem();
            creditInsuranceFundOccupationYearItem.setYear(year);
            List<TrustCreditInsuranceFundOccupationDetailItem> trustCreditInsuranceFundOccupationDetailItems = yearMap.get(year);
            trustCreditInsuranceFundOccupationDetailItems.sort(Comparator.comparing(TrustCreditInsuranceFundOccupationDetailItem::getOccupyDate).reversed());
            creditInsuranceFundOccupationYearItem.setYearTotal(NumberUtils.formatMoney(trustCreditInsuranceFundOccupationDetailItems.stream().mapToDouble(o -> Convert.toDouble(o.getOccupyAmount())).sum()));

            //金额格式化
            for (TrustCreditInsuranceFundOccupationDetailItem trustCreditInsuranceFundOccupationDetailItem : trustCreditInsuranceFundOccupationDetailItems) {
                trustCreditInsuranceFundOccupationDetailItem.setOccupyAmount(NumberUtils.formatMoney(trustCreditInsuranceFundOccupationDetailItem.getOccupyAmount()));
            }

            creditInsuranceFundOccupationYearItem.setCreditInsuranceFundOccupationList(trustCreditInsuranceFundOccupationDetailItems);
            creditInsuranceFundOccupationYearItems.add(creditInsuranceFundOccupationYearItem);
        }

        creditInsuranceFundOccupationYearItems.sort(Comparator.comparing(CreditInsuranceFundOccupationYearItem::getYear).reversed());

        //第一个展开
        if (CollUtil.isNotEmpty(creditInsuranceFundOccupationYearItems)) {
            creditInsuranceFundOccupationYearItems.get(0).setOpenFlag(BaseDict.OpenFlag.OPEN.getCode());
        }

        MftQueryCreditInsuranceFundOccupationRsp rsp = new MftQueryCreditInsuranceFundOccupationRsp();
        rsp.setCreditInsuranceFundOccupationTotal(NumberUtils.formatMoney(creditInsuranceFundOccupiedFundTotal));
        rsp.setCreditInsuranceFundOccupationYearList(creditInsuranceFundOccupationYearItems);

        return CommonResult.success(rsp);
    }

    /**
     * 2.2.10我的信托-信托利益分配
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.10我的信托-信托利益分配")
    @PostMapping(value = "/queryDistributionTrustBenefits")
    public CommonResult<MftQueryDistributionTrustBenefitsRsp> mftQueryDistributionTrustBenefits(@Valid @RequestBody MftQueryDistributionTrustBenefitsReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //受益人
        String beneficiary = req.getBeneficiary();

        //分配项目
        String distributionProject = req.getDistributionProject();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        String trustId = Convert.toStr(trust.getTrustId());
        //获得合同
        Contract contract = this.contractService.queryByTrustId(trustId);

        //先取交易记录的缓存
        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);

        String contractId = Convert.toStr(contract.getContractId());


        List<DistributionTrustBenefitsItem> distributionTrustBenefitsList = new ArrayList<>();

        //获得所有利益分配列表
        List<Distribution> distributionList = this.distributionService.queryDistributionByContractId(contractId);

        if (CollUtil.isNotEmpty(distributionList)) {
            for (Distribution distribution : distributionList) {
                DistributionTrustBenefitsItem distributionTrustBenefitsItem = new DistributionTrustBenefitsItem();

                //分配受益人
                String assignBeneficiaries = distribution.getContactsName();

                //分配项目类型
                String assignmentType = distribution.getFrequency();

                distributionTrustBenefitsItem.setBeneficiary(assignBeneficiaries);

                distributionTrustBenefitsItem.setDistributionProject(assignmentType);


                //支付频率
                String txType = Convert.toStr(distribution.getTxType());

                String txTypeStr = "";
                if (StrUtils.isNotBlank(txType) && !"0".equals(txType)) {
                    txTypeStr = EnumTools.getByCode(CrmDict.TxType.class, txType).getMessage();
                }

                //支付方式
                String payStyle = Convert.toStr(distribution.getPayStyle());
                String payStyleStr = EnumTools.getByCode(CrmDict.PayStyle.class, payStyle).getMessage();

                //分配标准=支付频率+支付方式
                distributionTrustBenefitsItem.setAllocationCriteria(txTypeStr + payStyleStr);

                List<CrmDistributionTrustBenefitsDetailItem> crmDistributionTrustBenefitsDetailItems = this.crmService.queryDistributionTrustBenefitsDetailByAssignBeneficiariesAndAssignmentType(assignBeneficiaries, assignmentType, crmData);

                if (CollUtil.isEmpty(crmDistributionTrustBenefitsDetailItems)) {
                    distributionTrustBenefitsItem.setDistributionFlag(BaseDict.DistributionStatus.D02.getMessage());
                    distributionTrustBenefitsItem.setCumulativeAllocatedAmount(NumberUtils.formatMoney(BigDecimal.ZERO));
                } else {

                    //利益分配执行记录表根据时间降序
                    crmDistributionTrustBenefitsDetailItems.sort(Comparator.comparing(CrmDistributionTrustBenefitsDetailItem::getMatchDate).reversed());

                    distributionTrustBenefitsItem.setDistributionFlag(BaseDict.DistributionStatus.D01.getMessage());
                    distributionTrustBenefitsItem.setCumulativeAllocatedAmount(NumberUtils.formatMoney(crmDistributionTrustBenefitsDetailItems.stream().mapToDouble(o -> Convert.toDouble(NumberUtils.formatNumber(o.getAllocationAmount()))).sum()));
                    List<DistributionExecutionRecordItem> distributionExecutionRecordItems = new ArrayList<>();

                    for (CrmDistributionTrustBenefitsDetailItem crmDistributionTrustBenefitsDetailItem : crmDistributionTrustBenefitsDetailItems) {
                        DistributionExecutionRecordItem distributionExecutionRecordItem = new DistributionExecutionRecordItem();
                        distributionExecutionRecordItem.setDistributionProject(assignmentType);
                        distributionExecutionRecordItem.setDistributionDate(DateUtils.format(crmDistributionTrustBenefitsDetailItem.getMatchDate(), "yyyy-MM-dd", "yyyy/MM/dd"));
                        distributionExecutionRecordItem.setDistributionAmount(NumberUtils.formatMoney(NumberUtils.formatNumber(crmDistributionTrustBenefitsDetailItem.getAllocationAmount())));
                        distributionExecutionRecordItems.add(distributionExecutionRecordItem);
                    }

                    //按时间排序
                    distributionExecutionRecordItems.sort(Comparator.comparing(DistributionExecutionRecordItem::getDistributionDate).reversed());

                    distributionTrustBenefitsItem.setDistributionExecutionRecord(distributionExecutionRecordItems);
                }

                distributionTrustBenefitsList.add(distributionTrustBenefitsItem);
            }
        }

        MftQueryDistributionTrustBenefitsRsp rsp = new MftQueryDistributionTrustBenefitsRsp();

        //v1.12
        //A.只填信托编号，返回这个信托编号下所有的利益分配计划。
        //B.只填信托编号+受益人，返回这个信托编号下这个受益人的利益分配计划。
        //C.只填信托编号+受益人+分配项目，只返回特定的利益分配记录。
        //D.其他情况都返回407接口参数异常。
        if (StrUtils.isBlank(beneficiary) && StrUtils.isBlank(distributionProject)) {
            rsp.setDistributionTrustBenefitsList(distributionTrustBenefitsList);
        } else if (StrUtils.isNotBlank(beneficiary) && StrUtils.isNotBlank(distributionProject)) {
            distributionTrustBenefitsList = distributionTrustBenefitsList.stream().filter(o -> o.getBeneficiary().equals(beneficiary)).collect(Collectors.toList());
            distributionTrustBenefitsList = distributionTrustBenefitsList.stream().filter(o -> o.getDistributionProject().equals(distributionProject)).collect(Collectors.toList());
            rsp.setDistributionTrustBenefitsList(distributionTrustBenefitsList);
        } else if (StrUtils.isNotBlank(beneficiary)) {
            distributionTrustBenefitsList = distributionTrustBenefitsList.stream().filter(o -> o.getBeneficiary().equals(beneficiary)).collect(Collectors.toList());
            rsp.setDistributionTrustBenefitsList(distributionTrustBenefitsList);
        } else {
            return CommonResult.error(ResponseCode.R407.getCode(), "受益人和项目有误！");
        }

        return CommonResult.success(rsp);
    }

    /**
     * 2.2.11我的信托-利益分配详情
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "2.2.11我的信托-利益分配详情")
    @PostMapping(value = "/queryBenefitDistributionDetails")
    public CommonResult<MftQueryBenefitDistributionDetailsRsp> mftQueryBenefitDistributionDetails(@Valid @RequestBody MftQueryBenefitDistributionDetailsReq req, BindingResult result, HttpServletRequest request) {

        //客户编号
        String customId = (String) request.getAttribute("identityId");

        String xtNumber = req.getXtNumber();

        //受益人
        String beneficiary = req.getBeneficiary();

        //分配项目
        String distributionProject = req.getDistributionProject();

        //客户
        Customer customer = this.customerService.getById(customId);
        if (customer == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "客户不存在");
        }

        //获得信托立项
        Trust trust = this.trustService.queryByXtNumber(xtNumber);
        if (trust == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "信托立项不存在");
        }

        //需对xtNumber 进行鉴权。
        if (!customId.equals(Convert.toStr(trust.getCustomerId()))) {
            return CommonResult.error(ResponseCode.R405.getCode(), ResponseCode.R405.getMessage());
        }

        String trustId = Convert.toStr(trust.getTrustId());
        //获得合同
        Contract contract = this.contractService.queryByTrustId(trustId);

        if (contract == null) {
            return CommonResult.error(ResponseCode.R407.getCode(), "合同不存在");
        }

        //先取交易记录的缓存
        CrmData crmData = this.crmService.queryCrmDateByXtNumber(xtNumber);

        //合同号
        String contractId = Convert.toStr(contract.getContractId());


        Distribution distribution = this.distributionService.queryBenefitDistributionByContractIdAndBeneficiaryAndDistributionProject(contractId, beneficiary, distributionProject);

        MftQueryBenefitDistributionDetailsRsp rsp = new MftQueryBenefitDistributionDetailsRsp();
        rsp.setBeneficiary(beneficiary);
        rsp.setRelationshipWithClient(distribution.getMatter());

        String beneficiaryType = Convert.toStr(distribution.getContactsType());
        rsp.setBeneficiaryType(EnumTools.getByCode(CrmDict.ContactsType.class, beneficiaryType).getMessage());

        rsp.setBankAccount(StrUtils.encryptedBankNumber(distribution.getBankNumber()));
        rsp.setOpenBank(distribution.getBankName());
        rsp.setAccountName(distribution.getAccountName());

        String payStyle = Convert.toStr(distribution.getPayStyle());

        rsp.setPaymentMethod(EnumTools.getByCode(CrmDict.PayStyle.class, payStyle).getMessage());

        rsp.setPaymentTerms(distribution.getPayQualification());

        String txType = Convert.toStr(distribution.getTxType());
        if (StrUtils.isNotBlank(txType) && !"0".equals(txType)) {
            rsp.setPaymentFrequency((EnumTools.getByCode(CrmDict.TxType.class, txType).getMessage()));
        }

        rsp.setDistributionProcedure(distribution.getFpchengxu());
        rsp.setIncomeRightTerm(distribution.getXtLiyi());
        rsp.setAllocationCriteria(distribution.getMode());
        rsp.setRemark(distribution.getFrequency());


        List<CrmDistributionTrustBenefitsDetailItem> crmDistributionTrustBenefitsDetailItems = this.crmService.queryDistributionTrustBenefitsDetailByAssignBeneficiariesAndAssignmentType(beneficiary, distributionProject, crmData);

        if (CollUtil.isNotEmpty(crmDistributionTrustBenefitsDetailItems)) {
            rsp.setDistributionFlag(BaseDict.DistributionStatus.D01.getMessage());

            crmDistributionTrustBenefitsDetailItems.sort(Comparator.comparing(CrmDistributionTrustBenefitsDetailItem::getMatchDate));

            String firstPaymentDate = crmDistributionTrustBenefitsDetailItems.get(0).getMatchDate();
            rsp.setFirstPaymentDate(firstPaymentDate);
        } else {
            rsp.setDistributionFlag(BaseDict.DistributionStatus.D02.getMessage());
        }

        rsp.setDistributionProject(distributionProject);

        String payMoneyStyle = Convert.toStr(distribution.getPayMoneyStyle());
        rsp.setPaymentAmountMethod((EnumTools.getByCode(CrmDict.PaymentAmountMethod.class, payMoneyStyle).getMessage()));

        return CommonResult.success(rsp);
    }
}
